package com.bp.hearthealth.pulse.lnapps.bp_view

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.DashPathEffect
import android.graphics.Paint
import android.graphics.RectF
import android.text.TextPaint
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.VelocityTracker
import android.view.View
import android.widget.Scroller
import com.bp.hearthealth.pulse.lnapps.R
import com.bp.hearthealth.pulse.lnapps.bp_extension.UIHelperBp
import com.bp.hearthealth.pulse.lnapps.bp_extension.dp2px
import com.bp.hearthealth.pulse.lnapps.bp_model.BarChartBeanBp
import com.bp.hearthealth.pulse.lnapps.bp_ui.bp_activity.bp_blood_pressure.BpBloodPressureStatus
import java.util.Collections

/**
 * @author isnoam
 * @package_name BarChartView
 * @date 2024-3-5
 * @description：
 */
class BPBarChartView @JvmOverloads constructor(
    context: Context?, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
    private var axisPaint: Paint? = null //画L线
    private val axisWidth = dp2px(2f) //线的宽度
    private val axisColor = Color.LTGRAY //线的颜色
    private val paddingLeft = dp2px(28f)
    private val paddingTop = dp2px(0f)
    private val paddingRight = dp2px(13f)
    private val paddingBottom = dp2px(10f)
    private val xTextHeight = dp2px(20f) //X轴底部文字高度
    private var axisTextPaint: TextPaint? = null //画坐标轴的文字
    private val axisTextSize = dp2px(12f) //文字大小
    private val axisTextColor = Color.BLACK
    private var axisXTextPaint: TextPaint? = null //画坐标轴的文字
    private val axisXTextSize = dp2px(12f) //文字大小
    private val axisXTextColor = Color.BLACK
    private var barTextPaint: TextPaint? = null //画坐标轴的文字
    private val barTextSize = dp2px(10f) //文字大小
    private var barTextColor = UIHelperBp.getColor(R.color.color_999999)
    private val barTextHeight = dp2px(10f)
    private var dashedLinePaint: Paint? = null
    private var ageY = 0f //平均没等分是多少
    private var barWidth = dp2px(20f) //柱子宽度
    private val barSpace = dp2px(15f) //柱子间距
    private var barPaint: Paint? = null //画柱子
    private var barColor = Color.GREEN //柱子颜色
    private var LegendPaint: Paint? = null
    private var legendTextPaint: TextPaint? = null
    private val legendTextColor = Color.BLACK
    private val legendTextSize = dp2px(10f)
    private var yBarList: MutableList<BarChartBeanBp> = mutableListOf() //y轴数据
    private var xAxisList: MutableList<String> = mutableListOf()
    private var yAxisList: MutableList<String> = mutableListOf()
    private var maxOffset = 0f
    private var lastX = 0f
    private var tracker: VelocityTracker? = null
    private var scroller: Scroller? = null
    private val cornerRadius = dp2px(15f).toFloat()
    private val dashedLinePaintHight = dp2px(1f)
    private var startNum = 20
    private var averageNum = 25
    private var average = 0

    init {
        init()
    }

    fun setBarTextColor(barTextColor: Int) {
        this.barTextColor = barTextColor
    }

    //设置柱子宽度
    fun setBarWidth(barWidth: Int) {
        this.barWidth = barWidth
    }

    //设置柱子颜色
    private fun setBarColor(barColor: Int) {
        this.barColor = barColor
        barPaint!!.color = barColor
    }

    //设置数据
    fun setChartData(
        xAxisList: MutableList<String>,
        yBarList: MutableList<BarChartBeanBp>
    ) {
        val yAxisList: MutableList<String> = ArrayList()
//        yAxisList.add("20")
//        yAxisList.add("70")
//        yAxisList.add("120")
//        yAxisList.add("160")
//        yAxisList.add("200")
//        yAxisList.add("240")
        yAxisList.add("20")
        yAxisList.add("45")
        yAxisList.add("70")
        yAxisList.add("95")
        yAxisList.add("120")
        yAxisList.add("145")
        yAxisList.add("170")
        yAxisList.add("195")
        yAxisList.add("220")
        this.yAxisList = yAxisList
        this.xAxisList = xAxisList
        this.yBarList = yBarList
        invalidate()
    }

    //得到Y轴最大值
    private fun maxYData(lists: List<Float>): Float {
        val hashSet = HashSet(lists)
        val list: List<Float> = ArrayList(hashSet)
        Collections.sort(list) //升序
        return list[list.size - 1]
    }

    private fun init() {
        axisPaint = Paint()
        axisPaint!!.strokeWidth = axisWidth.toFloat()
        axisPaint!!.color = axisColor
        axisPaint!!.flags = Paint.ANTI_ALIAS_FLAG
        axisPaint!!.isAntiAlias = true
        axisTextPaint = TextPaint()
        axisTextPaint!!.isAntiAlias = true
        axisTextPaint!!.flags = Paint.ANTI_ALIAS_FLAG
        axisTextPaint!!.textSize = axisTextSize.toFloat()
        axisTextPaint!!.color = axisTextColor
        axisXTextPaint = TextPaint()
        axisXTextPaint!!.isAntiAlias = true
        axisXTextPaint!!.flags = Paint.ANTI_ALIAS_FLAG
        axisXTextPaint!!.textSize = axisXTextSize.toFloat()
        axisXTextPaint!!.color = axisXTextColor
        barTextPaint = TextPaint()
        barTextPaint!!.isAntiAlias = true
        barTextPaint!!.flags = Paint.ANTI_ALIAS_FLAG
        barTextPaint!!.textSize = barTextSize.toFloat()
        barTextPaint!!.color = barTextColor
        barPaint = Paint()
        barPaint!!.color = barColor
        barPaint!!.flags = Paint.ANTI_ALIAS_FLAG
        barPaint!!.isAntiAlias = true
        LegendPaint = Paint()
        LegendPaint!!.color = barColor
        LegendPaint!!.flags = Paint.ANTI_ALIAS_FLAG
        LegendPaint!!.isAntiAlias = true
        legendTextPaint = TextPaint()
        legendTextPaint!!.isAntiAlias = true
        legendTextPaint!!.flags = Paint.ANTI_ALIAS_FLAG
        legendTextPaint!!.textSize = legendTextSize.toFloat()
        legendTextPaint!!.color = legendTextColor
        scroller = Scroller(context)

        dashedLinePaint = Paint()
        dashedLinePaint!!.color = Color.parseColor("#E1E1E1") // 设置虚线颜色
//        dashedLinePaint!!.color = Color.RED // 设置虚线颜色
        dashedLinePaint!!.style = Paint.Style.STROKE
        dashedLinePaint!!.strokeWidth = dashedLinePaintHight.toFloat() // 设置虚线宽度
        // 设置虚线效果
        val dashPathEffect = DashPathEffect(floatArrayOf(10f, 10f), 0f)
        dashedLinePaint!!.setPathEffect(dashPathEffect)
    }

    @SuppressLint("DrawAllocation")
    override fun onDraw(canvas: Canvas) {
        val width = measuredWidth
        val height = measuredHeight
        val maxTextWidth = axisTextPaint!!.measureText(300.toString()/*+ "0"*/) * 0.85f
        val left = paddingLeft + axisWidth / 2 + maxTextWidth //paddingLeft+线的宽度/2+Y轴值最大宽度
        val right = (width - paddingRight).toFloat()
        val top = paddingTop.toFloat()
        val bottom = (height - paddingBottom - axisWidth / 2).toFloat() //预留X轴文字高度
        canvas.save()
        canvas.translate(scrollX.toFloat(), 0f)
        //此处需减去xTextHeight / 3，否则顶部的文案显示不下
        ageY =
            (height - paddingBottom - paddingTop - (xTextHeight / 3)).toFloat() / yAxisList.size //线的每等分
        for (i in yAxisList.indices) {
            val average = startNum + i * averageNum
            val metricsInt = axisTextPaint!!.fontMetricsInt
            val dy = (metricsInt.bottom - metricsInt.top) / 2 - metricsInt.bottom
            val y = dy + (height - paddingBottom) - ageY * i - xTextHeight
            if (i == 0) {
                canvas.drawLine(
                    left, bottom - xTextHeight, right, bottom - xTextHeight, dashedLinePaint!!
                );//画X轴
                //画Y轴刻度
                canvas.drawText(
                    yAxisList[i],
                    maxTextWidth,
                    y,
                    axisTextPaint!!
                )
            } else {
                canvas.drawLine(
                    left, y - xTextHeight / 4, right, y - xTextHeight / 4, dashedLinePaint!!
                );//画X轴
                //画Y轴刻度
                if (yAxisList[i].length < 3) {
                    canvas.drawText(
                        (average).toString(), maxTextWidth, y, axisTextPaint!!
                    )
                } else {
                    //画Y轴刻度
                    canvas.drawText(
                        (average).toString(),
                        maxTextWidth - maxTextWidth / 4,
                        y,
                        axisTextPaint!!
                    )
                }
            }
        }
//        canvas.drawLine(left, top, left, bottom - xTextHeight, axisPaint!!);//画Y轴
//        canvas.drawLine(left, bottom - xTextHeight, right, bottom - xTextHeight, axisPaint!!);//画X轴
        for (i in yBarList.indices) {
            val x0 = left + (barSpace + barWidth) * i + barSpace + scrollX - 30
            val x1 = x0 + barWidth
            if (x1 <= left || x0 >= right) {
                continue
            }
            val top0 =
                (height - paddingBottom - (yBarList[i].maxValue - startNum) * ageY / averageNum - xTextHeight/* + xTextHeight / 4*/)
            val top1 =
                (height - paddingBottom - (yBarList[i].minValue - startNum) * ageY / averageNum - xTextHeight - dashedLinePaintHight /*+ xTextHeight / 4*/)
            canvas.clipRect(left, top, right, bottom) //剪切柱状图区域

            // 绘制具有圆角的矩形
            setBarColor(
                BpBloodPressureStatus.getBloodPressureStateOrColor(
                    1,
                    yBarList[i].maxValue,
                    yBarList[i].minValue
                )
            )
            val rectF = RectF(x0, top0, x1, top1)
            canvas.drawRoundRect(rectF, cornerRadius, cornerRadius, barPaint!!)

//            canvas.clipRect(x0, top0, x1, top1 - cornerRadius );  // 必须先设置显示区域再绘制
//            canvas.drawRoundRect(rectF, cornerRadius, cornerRadius, barPaint);

            //底部X轴文字
            val xtext = xAxisList[i]
            val xtextwidth = axisXTextPaint!!.measureText(xtext) //X文字宽度
            val metricsInt = axisXTextPaint!!.fontMetricsInt
            val dy = (metricsInt.bottom - metricsInt.top) / 2 - metricsInt.bottom
            val y = (height - xTextHeight + paddingBottom * 1.35 - dy).toFloat()
            canvas.drawText(xtext, x0 + (barWidth - xtextwidth) / 2f, y, axisXTextPaint!!)

            //柱状图上加文字
            val ytext = yBarList!![i].maxValue.toString()
            val ytextwidth = barTextPaint!!.measureText(ytext)
            canvas.drawText(
                ytext,
                x0 + (barWidth - ytextwidth) / 2f,
//                (top0 - barTextHeight.toFloat() / 2.5).toFloat(),
                (top0 - barTextHeight.toFloat() / 5).toFloat(),
                barTextPaint!!
            )
            val yMtext = yBarList!![i].minValue.toString()
            val yMTextwidth = barTextPaint!!.measureText(yMtext)
            canvas.drawText(
                yMtext,
                x0 + (barWidth - yMTextwidth) / 2f,
                top1 + barTextHeight.toFloat() - 5,
                barTextPaint!!
            )
        }
        maxOffset =
            yBarList!!.size * (barWidth + barSpace) - (measuredWidth - paddingRight - paddingLeft - maxTextWidth) //计算可滑动距离
        if (maxOffset < 0) {
            maxOffset = 0f
        }
        canvas.restore()
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                if (tracker != null) {
                    tracker!!.clear()
                }
                lastX = event.x
            }

            MotionEvent.ACTION_MOVE -> {
                if (tracker == null) {
                    tracker = VelocityTracker.obtain()
                }
                if (tracker != null) {
                    tracker!!.addMovement(event)
                }
                var sX = scrollX.toFloat()
                sX = (sX + (event.x - lastX)).toFloat()
                sX = Math.max(Math.min(0f, sX), -maxOffset)
                scrollTo(sX.toInt(), 0)
                lastX = event.x
            }

            MotionEvent.ACTION_UP -> setTracker()
            MotionEvent.ACTION_CANCEL -> setTracker()
        }
        invalidate()
        return true
    }

    private fun setTracker() {
        if (tracker != null) {
            tracker!!.computeCurrentVelocity(1000)
            scroller!!.forceFinished(true)
            scroller!!.fling(
                scrollX, 0, (0.5 * tracker!!.xVelocity).toInt(), 0, -maxOffset.toInt(), 0, 0, 0
            )
            tracker!!.recycle()
        }
        tracker = null
    }

    override fun computeScroll() {
        if (scroller!!.computeScrollOffset()) {
            scrollTo(scroller!!.currX, 0)
            postInvalidate()
        }
    }
}